import Message from 'element-ui/lib/message';
import MessageBox from 'element-ui/lib/message-box';

// 默认配置
const msgOptions = { confirmButtonText: '确认', cancelButtonText: '取消', showCancelButton: true, center: true, type: 'warning' };
const acceptTypes = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,.csv,text/plain';
const isPlainObject = val => Object.prototype.toString.call(val) === `[object Object]`; // 判断是否为原生

/**
 * 上传操作
 * @param {String} name 上传文件字段名
 * @param {Element} input 上传表单元素
 * @param {Function} callback 上传后回调函数
 * @returns
 */
function uploadAction(name, input, callback) {
  const files = input.files;
  const formData = new FormData();
  if (files.length < 1) return false;
  const fileData = files[0];
  const reader = new FileReader(); // 参数为 Blob 对象或 File 对象
  reader.onload = function() {
    formData.append(name, fileData);
    callback && callback(formData, fileData.name);
  };
  reader.readAsDataURL(fileData);
}

/**
 * 创建上传DOM
 * @param {String} name 上传文件字段名
 * @param {Function} callback 上传后回调函数
 */
function createImport(name, callback) {
  const input = document.createElement('input');
  input.type = 'file';
  input.accept = acceptTypes;
  input.multiple = false;
  input.click();
  input.addEventListener('change', () => uploadAction(name, input, callback), false);
}

/**
 * 导入装饰器
 * @param {String} name 导入时字段名称
 * @param {Object} data 导入时需要的参数
 * @param {String|Object} content 弹窗内容
 * @param {Object} option 弹窗的配置
 * @returns
 */
export default function({ name = 'file', data = {}, content = {}, option = {} }) {
  return function(target, propertyKey, descriptor) {
    const handler = descriptor.value;
    const options = Object.assign({}, msgOptions, option);

    descriptor.value = function(...args) {
      let form = Object.assign({}, data);
      let messageContent = null;
      const that = this._isVue ? this : target;
      const createElement = that.$createElement;
      if (typeof content === 'string') {
        messageContent = content;
      } else {
        messageContent = createElement('p', null, [
          createElement('span', null, content.text),
          createElement('a', { attrs: { style: { color: content.color || '#004fb3' }, href: content.url } }, content.name),
        ]);
      }

      MessageBox.confirm(messageContent, '导入提示', options)
        .then(() => {
          createImport(name, (data, file) => {
            args.forEach(item => (isPlainObject(item) ? (form = Object.assign({}, form, item)) : null));
            Object.entries(form).map(([key, val]) => data.append(key, val)); // 参数
            handler.apply(that, [data, file]);
          });
        })
        .catch(err => (err === 'cancel' ? Message.warning('你已取消了操作！') : console.log(err)));
    };
  };
}
